/**
 * @ProjectName:Backend
 * @Title: CustomerRealm
 * @Package com.phrp.shiro.realm
 * @Description: realm自定义类
 * @author SuShuChao
 * @date 2024/4/7 20:42
 * @version V1.0
 * Copyright (c) 2024, 2034279227@qq.com All Rights Reserved.
 */
package com.phrp.shiro;

import com.phrp.entity.ManagerUser;
import com.phrp.exception.CustomizationException;
import com.phrp.service.ManagerUserService;
import com.phrp.util.jwt.JwtUtil;
import com.phrp.util.returnResult.ReturnInfoEnum;
import io.jsonwebtoken.Claims;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;

public class AccountRealm extends AuthorizingRealm {

    @Autowired
    private ManagerUserService mUserService;

    @Autowired
    private JwtUtil jwtUtil;

    /**
     *  判断是否支持JwtToken
     */
    @Override
    public boolean supports(AuthenticationToken token) {
        return token instanceof JwtToken;
    }

    /**
     * 处理授权
     * <p>
     * ·当用户已通过认证，并尝试访问受保护的资源时，Shiro会调用此方法来获取用户的授权信息。
     * ·PrincipalCollection参数包含了已通过认证的用户信息。
     * ·在这个方法中，你需要根据用户的身份信息，从数据源中获取该用户的角色和权限信息，并封装成AuthorizationInfo对象返回给shiro。
     * <p>
     * @param principalCollection
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        System.out.println("=====用户授权=====");
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();

        /*获取当前的用户，已经登录后可以使用在任意的地方获取用户的信息*/
        String phone = (String) SecurityUtils.getSubject().getPrincipal();
        return null;
    }

    /**
     * 处理身份认证
     * <p>
     * ·当用户尝试登录时，shiro会调用此方法来获取认证信息。
     * ·AuthenticationToken包含了用户提交的身份（如用户名）、凭证（如密码）等信息。
     * ·在这个方法中，你需要根据用户提供的身份信息，从数据源（数据库）中获取对应的认证信息，
     * 并返回给shiro。如果认证失败，则抛出AuthenticationException异常
     *
     * @param token
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {

        System.out.println("=====用户验证=====");
        JwtToken jwtToken = (JwtToken) token;

        // 返回token中的主体部分的信息
        Claims claim = jwtUtil.getClaimByToken((String) jwtToken.getPrincipal());
        if(claim == null || jwtUtil.isTokenExpired(claim.getExpiration())){
            // 主体部分的信息为空或者是token失效了就抛出异常
            throw new CustomizationException(ReturnInfoEnum.SIGNATURE_NOT_MATCH);
        }

        // 获取其中的phone信息
        String phone = claim.getSubject();
        if(phone == null){
            throw new CustomizationException(ReturnInfoEnum.SIGNATURE_NOT_MATCH);
        }

        ManagerUser mUser = mUserService.getByPhone(phone);

        if(mUser == null){
            throw new CustomizationException(ReturnInfoEnum.SIGNATURE_NOT_MATCH);
        }

        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(mUser, token.getCredentials(), getName());
        return info;
    }
}